<template>
  <PanerForm :isShowBarDrawer="true" :caption="'编辑代理'">
    <template #body>
      <div class="d-row">
        <div class="d-form-group d-form-group-flex d-col-xs-12">
          <div class="d-form-label d-text-right">
            <label class="label-text">名称</label>
          </div>
          <div class="d-form-el">
            <input v-model="state.name" class="d-form-input" type="text" />
          </div>
        </div>
        <div class="d-form-group d-form-group-flex d-col-xs-12">
          <div class="d-form-label d-text-right">
            <label class="label-text">服务类型</label>
          </div>
          <div class="d-form-el">
            <FormSelecter
              v-model="state.serviceType"
              :data="serviceTypeList"
              :multiple="true"
              :valueType="'string'"
              value-key="id"
              :text-key="'text'"
              slide-max-height="200px" />
          </div>
        </div>
        <div class="d-form-group d-form-group-flex d-col-xs-12">
          <div class="d-form-label d-text-right">
            <label class="label-text">匹配规则</label>
          </div>
          <div class="d-form-el">
            <Table :data="state.matchRules">
              <TableColumn :field="'index'" type="index" label="序号" width="50" className="d-vm"></TableColumn>
              <TableColumn :field="'name'" label="名称" width="200" className="d-vm">
                <template v-slot:body="scope">
                  <div class="d-table-cell-editor">
                    <FormInput v-model="scope.name" />
                  </div>
                </template>
              </TableColumn>
              <TableColumn :field="'index'" label="匹配项" width="140">
                <template v-slot:body="scope">
                  <div class="d-table-cell-editor">
                  <select v-model="scope.matchItem" class="d-form-select">
                    <option v-for="item in matchItemList" :key="item.id" :value="item.id">{{ item.text }}</option>
                  </select>
                  </div>
                </template>
              </TableColumn>
              <TableColumn :field="'matchType'" label="匹配类型" width="140">
                <template v-slot:body="scope">
                  <div class="d-table-cell-editor">
                  <select v-model="scope.matchType" class="d-form-select">
                    <option v-for="item in matchTypeList" :key="item.id" :value="item.id">{{ item.text }}</option>
                  </select>
                  </div>
                </template>
              </TableColumn>
              <TableColumn :field="'matchValue'" label="匹配值" width="auto" className="d-vm">
                <template v-slot:body="scope">
                  <div class="d-table-cell-editor">
                    <a v-if="isFunction(scope.matchType)" @click="handleEditCoder(scope, 'matchValue')" class="d-tools-item d-text-theme">
                      <EditIcon size="sm" />
                    </a>
                    <input v-model="scope.matchValue" v-else-if="isRegexp(scope.matchType)" class="d-form-input" type="text" placeholder="/[a-z]+/" />
                    <input v-model="scope.matchValue" v-else class="d-form-input" type="text" />
                  </div>
                </template>
              </TableColumn>
              <TableColumn :field="'transformType'" label="匹配模式" width="100">
                <template v-slot:body="scope">
                  <div class="d-table-cell-editor">
                    <select v-model="scope.matchMode" class="d-form-select">
                      <option v-for="item in matchModeList" :key="item.id" :value="item.id">{{ item.text }}</option>
                    </select>
                  </div>
                </template>
              </TableColumn>
              <TableColumn :field="'order'" label="排序" width="60" className="d-vm">
                <template v-slot:body="scope">
                  <div class="d-table-cell-editor">
                    <FormInput v-model="scope.order" />
                  </div>
                </template>
              </TableColumn>
              <TableColumn field="action" label="操作" width="80" className="d-vm">
                <template v-slot:body="scope">
                  <div class="d-bar-tools d-bar-tools-condensed d-grid-actions">
                    <a @click="handleInsertItem('matchRules')" class="d-tools-item d-text-theme"><PlusIcon size="sm" /></a>
                    <a @click="handleDelItem('matchRules', scope)" class="d-tools-item d-text-theme"><DeleteIcon size="sm" /></a>
                  </div>
                </template>
              </TableColumn>
            </Table>
          </div>
        </div>
        <div class="d-form-group d-form-group-flex d-col-xs-12">
          <div class="d-form-label d-text-right">
            <label class="label-text">转换规则</label>
          </div>
          <div class="d-form-el">
            <Table :data="state.transformRules">
              <TableColumn :field="'index'" type="index" label="序号" width="50" className="d-vm"></TableColumn>
              <TableColumn :field="'name'" label="名称" width="200">
                <template v-slot:body="scope">
                  <div class="d-table-cell-editor">
                    <FormInput v-model="scope.name" />
                  </div>
                </template>
              </TableColumn>
              <TableColumn :field="'index'" label="转换项" width="140">
                <template v-slot:body="scope">
                  <div class="d-table-cell-editor">
                  <select v-model="scope.transformItem" class="d-form-select">
                    <option v-for="item in matchItemList" :key="item.id" :value="item.id">{{ item.text }}</option>
                  </select>
                  </div>
                </template>
              </TableColumn>
              <TableColumn :field="'transformType'" label="转换类型" width="140">
                <template v-slot:body="scope">
                  <div class="d-table-cell-editor">
                  <select v-model="scope.transformType" class="d-form-select">
                    <option v-for="item in transformTypeList" :key="item.id" :value="item.id">{{ item.text }}</option>
                  </select>
                  </div>
                </template>
              </TableColumn>
              <TableColumn :field="'transformValue'" label="转换值" width="auto" className="d-vm">
                <template v-slot:body="scope">
                  <div class="d-table-cell-editor">
                    <a v-if="isFunction(scope.transformType)" @click="handleEditCoder(scope, 'transformValue')" class="d-tools-item d-text-theme">
                      <EditIcon size="sm" />
                    </a>
                    <input v-model="scope.transformValue" v-else class="d-form-input" type="text" />
                  </div>
                </template>
              </TableColumn>
              <TableColumn :field="'transformMatch'" label="匹配规则" width="120">
                <template v-slot:body="scope">
                  <div class="d-table-cell-editor">
                     <FormSelecter
                      v-model="scope.transformMatch"
                      :data="state.matchRules"
                      :multiple="true"
                      value-key="id"
                      :text-key="'name'"
                      slide-max-height="200px" />
                  </div>
                </template>
              </TableColumn>
              <TableColumn :field="'transformType'" label="是否转换" width="100">
                <template v-slot:body="scope">
                  <div class="d-table-cell-editor">
                  <select v-model="scope.transformMode" class="d-form-select">
                    <option v-for="item in transformModeList" :key="item.id" :value="item.id">{{ item.text }}</option>
                  </select>
                  </div>
                </template>
              </TableColumn>
              <TableColumn :field="'order'" label="排序" width="60" className="d-vm">
                <template v-slot:body="scope">
                  <div class="d-table-cell-editor">
                    <FormInput v-model="scope.order" />
                  </div>
                </template>
              </TableColumn>
              <TableColumn field="action" label="操作" width="80" className="d-vm">
                <template v-slot:body="scope">
                  <div class="d-bar-tools d-bar-tools-condensed d-grid-actions">
                    <a @click="handleInsertItem('transformRules')" class="d-tools-item d-text-theme"><PlusIcon size="sm" /></a>
                    <a @click="handleDelItem('transformRules', scope)" class="d-tools-item d-text-theme"><DeleteIcon size="sm" /></a>
                  </div>
                </template>
              </TableColumn>
            </Table>
          </div>
        </div>
      </div>
      <div class="d-row">
        <div class="d-form-group d-form-group-flex d-col-xs-6">
          <div class="d-form-label d-text-right">
            <label class="label-text">匹配链接参数</label>
          </div>
          <div class="d-form-el">
            <Switcher v-model="state.isMatchParams" />
          </div>
        </div>
        <div class="d-form-group d-form-group-flex d-col-xs-6">
          <div class="d-form-label d-text-right">
            <label class="label-text">参数名</label>
          </div>
          <div class="d-form-el">
            <input v-model="state.matchParams" class="d-form-input" type="text" placeholder="多个使用逗号分隔" />
          </div>
        </div>
      </div>
      <div class="d-row">
        <div class="d-form-group d-form-group-flex d-col-xs-6">
          <div class="d-form-label d-text-right">
            <label class="label-text">匹配前Debugger</label>
          </div>
          <div class="d-form-el">
            <Switcher v-model="state.isBeforeDebugger" />
          </div>
        </div>
        <div class="d-form-group d-form-group-flex d-col-xs-6">
          <div class="d-form-label d-text-right">
            <label class="label-text">匹配后Debugger</label>
          </div>
          <div class="d-form-el">
            <Switcher v-model="state.isAfterDebugger" />
          </div>
        </div>
        <div class="d-form-group d-form-group-flex d-col-xs-12">
          <div class="d-form-label d-text-right">
            <label class="label-text">描述</label>
          </div>
          <div class="d-form-el">
            <FormTextarea v-model="state.description" :mode="STATUS.EDIT" />
          </div>
        </div>
        <div class="d-form-group d-form-group-flex d-col-xs-6">
          <div class="d-form-label d-text-right">
            <label class="label-text">状态</label>
          </div>
          <div class="d-form-el">
            <select v-model="state.status" class="d-form-select">
              <option v-for="item in statusList" :key="item.id" :value="item.id">{{ item.text }}</option>
            </select>
          </div>
        </div>
        <div class="d-form-group d-form-group-flex d-col-xs-6">
          <div class="d-form-label d-text-right">
            <label class="label-text">排序</label>
          </div>
          <div class="d-form-el">
            <input v-model="state.order" class="d-form-input" type="text" placeholder="数值越大越靠前" />
          </div>
        </div>
        <div class="d-form-group d-form-group-flex d-col-xs-6">
          <div class="d-form-label d-text-right">
            <label class="label-text">标签</label>
          </div>
          <div class="d-form-el">
            <input v-model="state.labels" class="d-form-input" type="text" />
          </div>
        </div>
        <FormCalendar
          v-if="isEdit"
          v-model="state.updateTime"
          :isEditAble="false"
          :readonly="true"
          format="yyyy-MM-dd HH:mm:ss"
          label="修改时间"
          labelWidth="90px"
          class="d-form-group-flex d-col-xs-6"
        ></FormCalendar>
        <div v-if="false && isEdit" class="d-form-group d-form-group-flex d-col-xs-6">
          <div class="d-form-label d-text-right">
            <label class="label-text">修改人</label>
          </div>
          <div class="d-form-el">
            <input v-model="state.updateUser" class="d-form-input" type="text" readonly />
          </div>
        </div>
        <FormCalendar
          v-if="isEdit"
          v-model="state.createTime"
          :isEditAble="false"
          :readonly="true"
          format="yyyy-MM-dd HH:mm:ss"
          label="创建时间"
          labelWidth="90px"
          class="d-form-group-flex d-col-xs-6"
        ></FormCalendar>
        <div v-if="false && isEdit" class="d-form-group d-form-group-flex d-col-xs-6">
          <div class="d-form-label d-text-right">
            <label class="label-text">创建人</label>
          </div>
          <div class="d-form-el">
            <input v-model="state.createUser" class="d-form-input" type="text" readonly />
          </div>
        </div>
      </div>
      <Dialoger v-model="isShowCoder" :onConfirm="handleSubmitCoder" :dialogCls="'d-paner-lg'" title="编辑">
        <template v-slot:body>
          <Coder v-model="coderValue" :height="'360px'" />
        </template>
      </Dialoger>
    </template>
    <template #bar-drawer>
      <button @click="handleSubmit" class="d-btn d-btn-primary" type="button">提交</button>
      <button v-if="!isEdit" @click="handleReset" class="d-btn d-btn-default" type="reset">重置</button>
      <a v-d-goback class="d-btn d-btn-default">返回</a>
    </template>
  </PanerForm>
</template>

<script>
import { PanerForm } from '@daelui/vdog/dist/pages'
import { Table, TableColumn, Dialoger, FormCalendar, FormSelecter, FormInput, Switcher, FormTextarea, Messager } from '@daelui/vdog/dist/components'
import { Coder } from '@daelui/vdog/dist/coder'
import { PlusIcon, DeleteIcon, EditIcon } from '@daelui/vdog/dist/icons'
import { objecter, coder, strer, parser } from '@daelui/dogjs/dist/components'
import { zh as locale } from '@daelui/dogjs/dist/locale'
import { STATUS } from '@daelui/dogjs/dist/constant'
import proxSer from '../../service/action/proxier.action.js'
import dictSer from '../../service/action/dictionary.action'
import { state, getter } from '../../service/stock/index'

export default {
  components: {
    Table,
    TableColumn,
    PanerForm,
    FormCalendar,
    FormSelecter,
    FormInput,
    FormTextarea,
    Switcher,
    Coder,
    PlusIcon,
    DeleteIcon,
    EditIcon,
    Dialoger
  },

  data () {
    return {
      STATUS,
      isEdit: false, // 是否是编辑模式
      // 表单数据
      state: {
        id: '',
        name: '',
        serviceType: 'ajax,fetch',
        order: 1,
        status: 1,
        labels: '',
        matchRules: [],
        transformRules: [],
        isMatchParams: false,
        isBeforeDebugger: false,
        isAfterDebugger: false,
        updateTime: '',
        updateUser: '',
        createTime: '',
        createUser: ''
      },
      // 请求方式
      methodList: [],
      // 协议类型
      protocolList: [],
      // 服务类型列表
      serviceTypeList: [],
      // 同步异步
      asyncList: [],
      // 状态
      statusList: getter.enableStatus(false),
      // 匹配方式
      matchTypeList: [
        {id: 'string', text: '字符串'},
        {id: 'regexp', text: '正则'},
        {id: 'function', text: '函数'}
      ],
      // 转换方式
      transformTypeList: [
        {id: 'string', text: '字符串'},
        {id: 'function', text: '函数'}
      ],
      matchModeList: [
        {id: 'or', text: '或'},
        {id: 'and', text: '与'},
        {id: '', text: '不匹配'}
      ],
      transformModeList: [
        {id: '1', text: '是'},
        {id: '0', text: '否'}
      ],
      matchItemList: [
        {id: 'url', text: '地址'},
        {id: 'method', text: '请求方式'},
        {id: 'async', text: '异步方式'},
        {id: 'reqHeaderKey', text: '请求头键'},
        {id: 'reqHeaderValue', text: '请求头值'},
        {id: 'request', text: '请求数据'},
        {id: 'response', text: '响应数据'}
      ],
      isShowCoder: false,
      coderValue: ''
    }
  },

  methods: {
    /**
     * @function 加载笔记
    */
    loadItem (id) {
      proxSer.queryItem({ id }).then(result => {
        let data = result.data || {}
        // 匹配规则
        data.matchRules = parser.parse(data.matchRules, 'json')
        data.matchRules = Array.isArray(data.matchRules) ? data.matchRules : []
        data.matchRules = data.matchRules.sort((a, b) => {
          return a.order > b.order ? -1 : a.order < b.order ? 1 : 0
        })
        // 转换规则
        data.transformRules = parser.parse(data.transformRules, 'json')
        data.transformRules = Array.isArray(data.transformRules) ? data.transformRules : []
        data.transformRules = data.transformRules.sort((a, b) => {
          return a.order > b.order ? -1 : a.order < b.order ? 1 : 0
        })
        this.state = data
        if (this.state.matchRules.length === 0) {
          this.handleInsertItem('matchRules')
        }
        if (this.state.transformRules.length === 0) {
          this.handleInsertItem('transformRules')
        }
      })
    },

    /**
     * @function 提交
    */
    handleSubmit () {
      let defer = null
      let data = objecter.clone(this.state)
      data.matchRules = parser.stringify(data.matchRules)
      data.transformRules = parser.stringify(data.transformRules)
      // 编辑
      if (this.isEdit) {
        defer = proxSer.editItem(data)
      } else { // 添加
        defer = proxSer.addItem(data)
      }
      defer.then(result => {
        if (result.success) {
          Dialoger.success(locale.action.success)
        } else {
          Dialoger.danger(locale.action.fail)
        }
        // 添加则回到列表页
        if (!this.isEdit) {
          this.$router.push(this.getMicroRoute('/proxier/list'))
        }
      })
    },
    /**
     * @function 重置
    */
    handleReset () {

    },

    isFunction (type) {
      let matchTypeList = this.matchTypeList
      return String(matchTypeList[2].id) === String(type)
    },

    isRegexp (type) {
      let matchTypeList = this.matchTypeList
      return String(matchTypeList[1].id) === String(type)
    },

    handleEditCoder (item, key) {
      this.isShowCoder = true
      this.editNode = item
      this.editKey = key
      this.coderValue = this.editNode[key] || 'export default function () {\n\n}'
    },

    handleSubmitCoder () {
      // 编译
      let code = ''
      try {
        code = coder.transformModule(this.coderValue)
      } catch (e) {
        code = ''
        Messager.warn('解析失败')
        return false
      }
      let key = this.editKey
      this.isShowCoder = false
      this.editNode[key] = this.coderValue
      this.editNode[key + 'Compiled'] = code
    },

    /**
     * @function 添加单条数据
    */
    handleInsertItem (name) {
      let rules = this.state[name]
      rules = Array.isArray(rules) ? rules : []
      let rule = {
        id: strer.utid(),
        name: strer.uuid(6),
        matchItem: 'url',
        matchType: 'string',
        matchMode: this.matchModeList[0].id
      }
      if (/transform/.test(name)) {
        rule = {
          id: strer.utid(),
          name: strer.uuid(6),
          transformItem: 'url',
          transformType: 'string',
          transformMode: this.transformModeList[0].id
        }
      }
      rules.push(rule)
      this.state[name] = rules
    },

    /**
     * @function 删除单条数据
    */
    handleDelItem (name, item) {
      let rules = this.state[name]
      rules = Array.isArray(rules) ? rules : []
      rules = rules.filter(node => {
        return item !== node
      })
      this.state[name] = rules
    }
  },

  beforeMount () {
    let params = this.$route.params
    // 新建
    if (!params.id) {
      this.isEdit = false
      this.handleInsertItem('matchRules')
      this.handleInsertItem('transformRules')
    } else { // 编辑
      this.isEdit = true
      this.loadItem(params.id)
    }
  },

  mounted () {
    // 查询请求协议类型列表
    dictSer.queryProtocolList().then(list => {
      list = Array.isArray(list) ? list : []
      list.unshift({id: '', value: '', text: '全部'})
      this.protocolList = list
    })
    // 查询请求方式列表
    dictSer.queryMethodList().then(list => {
      list = Array.isArray(list) ? list : []
      list.unshift({id: '', value: '', text: '全部'})
      this.methodList = list
    })
    // 查询服务类型列表
    dictSer.queryServiceTypeList().then(list => {
      list = Array.isArray(list) ? list : []
      list.unshift({id: '', value: '', text: '全部'})
      this.serviceTypeList = list
    })
    // 查询异步类型列表
    dictSer.queryAsyncList().then(list => {
      list = Array.isArray(list) ? list : []
      list.unshift({id: '', value: '', text: '全部'})
      this.asyncList = list
    })
  }
}
</script>

<style lang="less" scoped>
.d-form-label {
  width: 90px;
}
.d-form-textarea {
  min-height: 320px;
}
.d-form-group /deep/.ql-container .ql-editor {
  min-height: 200px;
}
</style>
